package SyntheticData;

import java.util.ArrayList;

/**
 *
 */
public class DeterministicBuilder {
    private Graph graph;
    private int numLabels;
    private int numElements;
    private int numNetworkElements;
    private int numContentElements;
    private int numSharedElements;

    DeterministicBuilder(int numLabels, int numElements, int numNetworkElements,
            int numContentElements, int numSharedElements) {
        this.numLabels = numLabels;
        this.numElements = numElements;
        this.numNetworkElements = numNetworkElements;
        this.numContentElements = numContentElements;
        this.numSharedElements = numSharedElements;
    }

    public Graph getGraph() {
        return graph;
    }

    private double similarity(Vertex v, Vertex w) {
        if (numNetworkElements != 0) {
            int matches = 0;
            for (int i = 0; i < numNetworkElements; i++) {
                if (v.getElement(i) == w.getElement(i)) {
                    matches++;
                }
            }
            return (double) matches / (double) numNetworkElements;
        } else {
            return 0.5;
        }
    }

    private ArrayList<Vertex> connect(Vertex v, double similarityThreshold) {
        ArrayList<Vertex> a = new ArrayList<Vertex>();
        for (int j = 0; j < graph.numVertices(); j++) {
            Vertex w = graph.getVertex(j);
            if (similarity(v, w) >= similarityThreshold) {
                a.add(w);
            }
        }
        return a;
    }

    /**
     * Creates a new graph according to the static StringNet model.
     * Resulting graph can be accessed via getGraph().
     * @param numVertices number of vertices to be initiated.
     * @param similarityThreshold deterministic similarity threshold
     * @param biasedProb probability of biased label
     */
    public void build(int numVertices, double similarityThreshold,
            double biasedProb) {
    	
    	System.out.println("biasedProb:"+biasedProb);
        graph = new Graph();

        for (int i = 0; i < numVertices; i++) {
            Vertex v = new Vertex(i, numElements);
            v.randomizeElements(numLabels, biasedProb);
            v.determineLabel(numLabels);
            graph.addVertex(v);
        }

        for (int i = 0; i < numVertices; i++) {
            Vertex v = graph.getVertex(i);
            ArrayList<Vertex> a = new ArrayList<Vertex>();
            for (int j = 0; j < numVertices; j++) {
                Vertex w = graph.getVertex(j);
                if (v != w && similarity(v, w) >= similarityThreshold) {
                    a.add(w);
                }
            }
            graph.addArcs(a);
        }
    }

    /**
     * Grows the graph by inserting new vertices and arcs according to the
     * dynamic StringNet model.
     * Resulting graph can be accessed via getGraph().
     * @param numVertices number of new vertices to be inserted
     * @param similarityThreshold deterministic similarity threshold
     * @param reassignProb reassignment probability of elements during mutation
     */
    public void grow(int numVertices, double similarityThreshold,
            double reassignProb) {
        int indexOffset = graph.numVertices();
        for (int i = 0; i < numVertices; i++) {
            Vertex w = graph.randomVertex();
            Vertex v = new Vertex(indexOffset + i, w);
            v.mutateElements(numLabels, reassignProb);
            v.determineLabel(numLabels);
            ArrayList<Vertex> a = connect(v, similarityThreshold);
            graph.addVertex(v);
            graph.addArcs(a);
        }
    }
}
